﻿using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace ParkingYunService
{
    public class SendDatas
    {
        /// <summary>
        /// 编码
        /// </summary>
        private static Encoding gbkencoding = Encoding.GetEncoding(936);
        static WeChatParking.Core.BLL.ServerCode bll = new WeChatParking.Core.BLL.ServerCode();
        #region 被动
        /// <summary>
        /// 被动数据处理
        /// </summary>
        /// <param name="RcvData">返回响应数据</param>
        /// <returns></returns>
        public static byte[] beiDongSendData(string IpAndPort, byte[] RcvData, ref string code)
        {
            if (RcvData.Length < 36)
                return ByteUtil.getBytes(PublicManage.formatInt(1000, 4));
            else
            {
                PublicManage.api_secret = "asdf123";
                try
                {
                    ////签名长度
                    //byte[] SignLenArr = new byte[10];
                    //Array.Copy(RcvData, 0, SignLenArr, 0, 10);
                    //int Signlen = Convert.ToInt32(System.Text.Encoding.UTF8.GetString(SignLenArr));
                    int Signlen = 32;
                    //功能号
                    byte[] Func_noArr = new byte[1];
                    Array.Copy(RcvData, 10 + Signlen, Func_noArr, 0, 1);
                    int Func_no = Convert.ToInt32(System.Text.Encoding.UTF8.GetString(Func_noArr));
                    //签名
                    byte[] signArr = new byte[Signlen];
                    Array.Copy(RcvData, 10, signArr, 0, Signlen);
                    string Sign = System.Text.Encoding.UTF8.GetString(signArr);
                    switch (Func_no)
                    {
                        case (short)WeChatParking.Entity.Enums.Func_no.Heartbeat:
                            return heartbeat(RcvData, Sign, Signlen, ref code);
                        case (short)WeChatParking.Entity.Enums.Func_no.inOrOut:
                            return inOrOut(RcvData, Sign, Signlen, ref code);
                        case (short)WeChatParking.Entity.Enums.Func_no.YPay:
                            return YPay(RcvData, Sign, Signlen);
                        case (short)WeChatParking.Entity.Enums.Func_no.XCPay:
                            return XCPay(RcvData, Sign, Signlen, ref code);
                        case (short)WeChatParking.Entity.Enums.Func_no.FeeQuery:
                            return FeeQuery(RcvData, Sign, Signlen);
                        default:
                            return ByteUtil.getBytes(PublicManage.formatInt(1000, 4));
                    }
                }
                catch (Exception e)
                {
                    LogManage.WriteLog("异常地址" + IpAndPort, e.ToString());
                    return ByteUtil.getBytes(PublicManage.formatInt(1000, 4));
                }
            }
        }
        /// <summary>
        /// 心跳包
        /// </summary>
        /// <param name="RcvData"></param>
        /// <param name="Sign"></param>
        /// <param name="Signlen"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private static byte[] heartbeat(byte[] RcvData, string Sign, int Signlen, ref string code)
        {
            bool SignState = false;
            //客户端代码
            byte[] Parking_codeArr = new byte[16];
            Array.Copy(RcvData, 11 + Signlen, Parking_codeArr, 0, 16);
            byte[] buf1 = Encoding.Convert(gbkencoding, Encoding.Unicode, Parking_codeArr);
            string Parking_code = Encoding.Unicode.GetString(buf1);

            //Guid
            byte[] GuidArr = new byte[32];
            Array.Copy(RcvData, 11 + Signlen + 16, GuidArr, 0, 32);
            byte[] buf3 = Encoding.Convert(gbkencoding, Encoding.Unicode, GuidArr);
            WeChatParking.Entity.Api.Heartbeat model = new WeChatParking.Entity.Api.Heartbeat();
            model.Signlen = Signlen;
            model.Sign = Sign;
            model.Func_no = (short)WeChatParking.Entity.Enums.Func_no.Heartbeat;
            model.Parking_code = Parking_code;
            code = Parking_code;
            model.Guid = Encoding.Unicode.GetString(buf3);
            SignState = PublicManage.CheckSign(model, Sign);
            if (SignState)
            {
                if (bll.ExistsClient_code(model.Parking_code))
                    return sendData(WeChatParking.Entity.Enums.Func_no.Heartbeat, WeChatParking.Entity.Enums.State.OK, model.Guid);
                else
                    return sendData(WeChatParking.Entity.Enums.Func_no.Heartbeat, WeChatParking.Entity.Enums.State.errCode, model.Guid);
            }
            else
                return sendData(WeChatParking.Entity.Enums.Func_no.Heartbeat, WeChatParking.Entity.Enums.State.errSign, model.Guid);
        }
        /// <summary>
        /// 进出场记录
        /// </summary>
        /// <param name="RcvData"></param>
        /// <param name="Sign"></param>
        /// <param name="Signlen"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private static byte[] inOrOut(byte[] RcvData, string Sign, int Signlen, ref string code)
        {
            bool SignState = false;
            //车场客户端代码
            byte[] Parking_codeArr = new byte[16];
            Array.Copy(RcvData, 11 + Signlen, Parking_codeArr, 0, 16);
            byte[] buf1 = Encoding.Convert(gbkencoding, Encoding.Unicode, Parking_codeArr);
            string Parking_code = Encoding.Unicode.GetString(buf1);

            WeChatParking.Entity.Api.InOrOut model = new WeChatParking.Entity.Api.InOrOut();
            //车牌
            byte[] Car_plateArr = new byte[16];
            Array.Copy(RcvData, 11 + Signlen + 16, Car_plateArr, 0, 16);
            byte[] buf2 = Encoding.Convert(gbkencoding, Encoding.Unicode, Car_plateArr);
            //时间
            byte[] TimeArr = new byte[12];
            Array.Copy(RcvData, 11 + Signlen + 32, TimeArr, 0, 12);
            //类型
            byte[] TypeArr = new byte[1];
            Array.Copy(RcvData, 11 + Signlen + 44, TypeArr, 0, 1);
            //车型
            byte[] Car_TypeArr = new byte[1];
            Array.Copy(RcvData, 11 + Signlen + 45, Car_TypeArr, 0, 1);
            //图片长度
            byte[] ImgLenArr = new byte[10];
            Array.Copy(RcvData, 11 + Signlen + 46, ImgLenArr, 0, 10);
            //Guid
            byte[] GuidArr = new byte[32];
            Array.Copy(RcvData, 11 + Signlen + 56, GuidArr, 0, 32);
            byte[] buf3 = Encoding.Convert(gbkencoding, Encoding.Unicode, GuidArr);
            // 车主用户类型
            byte[] CarUser_typeArr = new byte[1];
            Array.Copy(RcvData, 11 + Signlen + 88, CarUser_typeArr, 0, 1);
            //图片
            int imgLen = Convert.ToInt32(System.Text.Encoding.UTF8.GetString(ImgLenArr));
            byte[] ImgArr = new byte[imgLen];
            Array.Copy(RcvData, 11 + Signlen + 89, ImgArr, 0, imgLen);
            model.Signlen = Signlen;
            model.Sign = Sign;
            model.Func_no = (short)WeChatParking.Entity.Enums.Func_no.inOrOut;
            model.Parking_code = Parking_code;
            code = Parking_code;
            model.Car_plate = Encoding.Unicode.GetString(buf2).Trim();
            model.Time = System.Text.Encoding.UTF8.GetString(TimeArr);
            model.Type = Convert.ToInt32(System.Text.Encoding.UTF8.GetString(TypeArr));
            model.Car_type = Convert.ToInt32(System.Text.Encoding.UTF8.GetString(Car_TypeArr));
            model.ImgLen = imgLen;
            model.Guid = Encoding.Unicode.GetString(buf3);
            model.CarUser_type = Convert.ToInt32(System.Text.Encoding.UTF8.GetString(CarUser_typeArr));
            model.Img = ImgArr;
            SignState = PublicManage.CheckSign(model, Sign);
            if (SignState)//签名通过
            {
                if (bll.ExistsClient_code(model.Parking_code))
                {
                    //保存图片
                    string R_startPath = Application.StartupPath;
                    if (!Directory.Exists(R_startPath + "\\Img\\" + DateTime.Now.ToString("yyyyMMdd")))//判断是否存在路径
                    {
                        Directory.CreateDirectory(R_startPath + "\\Img\\" + DateTime.Now.ToString("yyyyMMdd"));
                    }
                    string FileName = "\\Img\\" + DateTime.Now.ToString("yyyyMMdd") + "\\" + model.Guid + ".jpg";
                    switch (model.Type)
                    {
                        case 0:
                            if (bll.ServerAddIn(model, FileName) > 0)
                            {
                                FileStream fs = File.Create(R_startPath + FileName);
                                fs.Write(ImgArr, 0, ImgArr.Length);
                                fs.Close();
                                return sendData(WeChatParking.Entity.Enums.Func_no.inOrOut, WeChatParking.Entity.Enums.State.OK, model.Guid);
                            }
                            else
                                return sendData(WeChatParking.Entity.Enums.Func_no.inOrOut, WeChatParking.Entity.Enums.State.errNo, model.Guid);
                        case 1:
                            if (bll.ServerAddOut(model, FileName))
                            {
                                FileStream fs = File.Create(R_startPath + FileName);
                                fs.Write(ImgArr, 0, ImgArr.Length);
                                fs.Close();
                                return sendData(WeChatParking.Entity.Enums.Func_no.inOrOut, WeChatParking.Entity.Enums.State.OK, model.Guid);
                            }
                            else
                                return sendData(WeChatParking.Entity.Enums.Func_no.inOrOut, WeChatParking.Entity.Enums.State.errNo, model.Guid);
                    }
                }
                else
                    return sendData(WeChatParking.Entity.Enums.Func_no.inOrOut, WeChatParking.Entity.Enums.State.errCode, model.Guid);
            }
            else
                return sendData(WeChatParking.Entity.Enums.Func_no.inOrOut, WeChatParking.Entity.Enums.State.errSign, model.Guid);
            return sendData(WeChatParking.Entity.Enums.Func_no.inOrOut, WeChatParking.Entity.Enums.State.errData, model.Guid);
        }

        /// <summary>
        /// 预支付
        /// </summary>
        /// <param name="RcvData"></param>
        /// <param name="Sign"></param>
        /// <param name="Signlen"></param>
        /// <returns></returns>
        private static byte[] YPay(byte[] RcvData, string Sign, int Signlen)
        {
            bool SignState = false;
            WeChatParking.Entity.Api.StateYD model = new WeChatParking.Entity.Api.StateYD();
            //状态
            byte[] StateArr = new byte[1];
            Array.Copy(RcvData, 11 + Signlen, StateArr, 0, 1);
            //Guid
            byte[] GuidArr = new byte[32];
            Array.Copy(RcvData, 11 + Signlen + 1, GuidArr, 0, 32);
            byte[] buf3 = Encoding.Convert(gbkencoding, Encoding.Unicode, GuidArr);
            model.Signlen = Signlen;
            model.Sign = Sign;
            model.Func_no = (short)WeChatParking.Entity.Enums.Func_no.YPay;
            model.State = Convert.ToInt32(System.Text.Encoding.UTF8.GetString(StateArr));
            model.Guid = Encoding.Unicode.GetString(buf3);
            SignState = PublicManage.CheckSign(model, Sign);
            if (SignState)
            {
                if (model.State == (short)WeChatParking.Entity.Enums.State.OK)
                {
                    bll.UpdateYPay(model.Guid, 3);
                }
                else
                {
                    bll.UpdateYPay(model.Guid, 0);
                }
                return null;
            }
            else
            {
                return sendData(WeChatParking.Entity.Enums.Func_no.YPay, WeChatParking.Entity.Enums.State.errSign, model.Guid);
            }
        }
        /// <summary>
        /// 车开到现场门岗 客户端推送过来
        /// </summary>
        /// <param name="RcvData"></param>
        /// <param name="Sign"></param>
        /// <param name="Signlen"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private static byte[] XCPay(byte[] RcvData, string Sign, int Signlen, ref string code)
        {
            bool SignState = false;
            //车场客户端代码
            byte[] Parking_codeArr = new byte[16];
            Array.Copy(RcvData, 11 + Signlen, Parking_codeArr, 0, 16);
            byte[] buf1 = Encoding.Convert(gbkencoding, Encoding.Unicode, Parking_codeArr);
            string Parking_code = Encoding.Unicode.GetString(buf1);
            WeChatParking.Entity.Api.XCPay model = new WeChatParking.Entity.Api.XCPay();
            //车牌
            byte[] Car_plateArr = new byte[16];
            Array.Copy(RcvData, 11 + Signlen + 16, Car_plateArr, 0, 16);
            byte[] buf2 = Encoding.Convert(gbkencoding, Encoding.Unicode, Car_plateArr);
            //时间
            byte[] TimeArr = new byte[12];
            Array.Copy(RcvData, 11 + Signlen + 32, TimeArr, 0, 12);
            //费用
            byte[] FeeArr = new byte[8];
            Array.Copy(RcvData, 11 + Signlen + 44, FeeArr, 0, 8);
            //Guid
            byte[] GuidArr = new byte[32];
            Array.Copy(RcvData, 11 + Signlen + 52, GuidArr, 0, 32);
            byte[] buf3 = Encoding.Convert(gbkencoding, Encoding.Unicode, GuidArr);
            model.Signlen = Signlen;
            model.Sign = Sign;
            model.Func_no = (short)WeChatParking.Entity.Enums.Func_no.XCPay;
            model.Parking_code = Parking_code;
            code = Parking_code;
            model.Car_plate = Encoding.Unicode.GetString(buf2).Trim();
            model.Time = System.Text.Encoding.UTF8.GetString(TimeArr);
            model.Fee = Convert.ToInt32(System.Text.Encoding.UTF8.GetString(FeeArr));
            model.Guid = Encoding.Unicode.GetString(buf3);
            SignState = PublicManage.CheckSign(model, Sign);
            if (SignState)//签名通过
            {
                if (bll.XCPay(model))
                    return sendData(WeChatParking.Entity.Enums.Func_no.XCPay, WeChatParking.Entity.Enums.State.OK, model.Guid);
                else
                    return sendData(WeChatParking.Entity.Enums.Func_no.XCPay, WeChatParking.Entity.Enums.State.errNo, model.Guid);
            }
            else
            {
                return sendData(WeChatParking.Entity.Enums.Func_no.XCPay, WeChatParking.Entity.Enums.State.errSign, model.Guid);
            }
        }
        /// <summary>
        /// 费用查询
        /// </summary>
        /// <param name="RcvData"></param>
        /// <param name="Sign"></param>
        /// <param name="Signlen"></param>
        /// <returns></returns>
        private static byte[] FeeQuery(byte[] RcvData, string Sign, int Signlen)
        {
            bool SignState = false;
            //金额
            byte[] FeeArr = new byte[5];
            Array.Copy(RcvData, 11 + Signlen, FeeArr, 0, 1);
            //Guid
            byte[] GuidArr = new byte[32];
            Array.Copy(RcvData, 11 + Signlen + 1, GuidArr, 0, 32);
            byte[] buf3 = Encoding.Convert(gbkencoding, Encoding.Unicode, GuidArr);
            WeChatParking.Entity.Api.StateFee model = new WeChatParking.Entity.Api.StateFee();
            model.Sign = Sign;
            model.Signlen = Signlen;
            model.Guid = Encoding.Unicode.GetString(buf3);
            model.Func_no = (short)WeChatParking.Entity.Enums.Func_no.FeeQuery;
            model.Fee = Convert.ToInt32(System.Text.Encoding.UTF8.GetString(FeeArr));
            SignState = PublicManage.CheckSign(model, Sign);
            if (SignState)
            {
                try
                {
                    bll.UpdateFeeQuery(model.Guid, 3, model.Fee);
                }
                catch (Exception)
                {
                    bll.UpdateFeeQuery(model.Guid, 0, model.Fee);
                    return null;
                }
                return null;
            }
            else
            {
                return sendData(WeChatParking.Entity.Enums.Func_no.FeeQuery, WeChatParking.Entity.Enums.State.errSign, model.Guid);
            }

        }
        /// <summary>
        /// 生成发送的byte
        /// </summary>
        /// <param name="Func_no"></param>
        /// <param name="state"></param>
        /// <param name="Guid"></param>
        /// <returns></returns>
        private static byte[] sendData(WeChatParking.Entity.Enums.Func_no Func_no, WeChatParking.Entity.Enums.State state, string Guid)
        {
            WeChatParking.Entity.Api.StateYD model = new WeChatParking.Entity.Api.StateYD();
            model.Signlen = 0;
            model.Sign = "";
            model.Func_no = (short)Func_no;
            model.State = (short)state;
            model.Guid = Guid;
            string Sign = PublicManage.GetSign(model);
            var SignArr = ByteUtil.getBytes(Sign);
            int Signlen = SignArr.Length;
            model.Signlen = Signlen;
            var SignLenArr = ByteUtil.getBytes(PublicManage.formatInt(model.Signlen, 10));
            var Func_noArr = ByteUtil.getBytes(PublicManage.formatInt((short)model.Func_no, 1));
            var StateArr = ByteUtil.getBytes(PublicManage.formatInt((short)model.State, 1));
            var GuidArr = ByteUtil.getBytes(PublicManage.formatTxt(model.Guid, 32));
            var Arr = (((
                SignLenArr.Concat(SignArr).ToArray())
                .Concat(Func_noArr).ToArray())
                .Concat(StateArr).ToArray())
                .Concat(GuidArr).ToArray();
            return Arr;
        }
        #endregion

        #region 主动
        /// <summary>
        /// 主动发送预缴费用
        /// </summary>
        /// <param name="IpAndPort"></param>
        /// <returns></returns>
        public static byte[] zhuDongYPay(WeChatParking.Entity.Api.YPay ypay, ref string code)
        {
            if (ypay != null)
            {
                code = ypay.DeviceClient_code;
                WeChatParking.Entity.Api.ApiYPay model = new WeChatParking.Entity.Api.ApiYPay();
                model.Signlen = 0;
                model.Sign = "";
                model.Func_no = (short)WeChatParking.Entity.Enums.Func_no.YPay;
                model.Car_plate = ypay.Car_plate;
                model.Time = ypay.Time;
                model.Fee = ypay.Fee;
                model.CarUser_type = ypay.CarUser_type;
                model.Guid = ypay.Guid;
                string Sign = PublicManage.GetSign(model);
                var SignArr = ByteUtil.getBytes(Sign);
                model.Signlen = SignArr.Length;
                model.Sign = Sign;
                //签名长度
                var SignLenArr = ByteUtil.getBytes(PublicManage.formatInt(model.Signlen, 10));
                //功能号
                var Func_noArr = ByteUtil.getBytes(PublicManage.formatInt((short)model.Func_no, 1));
                //车牌
                var Car_plateArr = ByteUtil.getBytes(PublicManage.formatTxt(model.Car_plate, 16));
                //时间
                var TimeArr = ByteUtil.getBytes(model.Time);
                //费用
                var FeeArr = ByteUtil.getBytes(PublicManage.formatInt(model.Fee, 8));
                //车主用户类型
                var Car_TypeArr = ByteUtil.getBytes(PublicManage.formatInt(model.CarUser_type, 1));
                //Guid
                var GuidArr = ByteUtil.getBytes(PublicManage.formatTxt(model.Guid, 32));
                var byteArray = (((((//签名长度
                    (SignLenArr.Concat(SignArr).ToArray())//签名
                    .Concat(Func_noArr).ToArray())//功能号
                    .Concat(Car_plateArr).ToArray())//车牌号
                    .Concat(TimeArr).ToArray())//时间
                    .Concat(FeeArr).ToArray())//费用
                     .Concat(Car_TypeArr).ToArray())//车主用户类型
                    .Concat(GuidArr).ToArray();//Guid
                return byteArray;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// 主动发送费用查询
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static byte[] zhuDongFeeQuery(WeChatParking.Entity.Api.FeeQuery feeQuery, ref string code)
        {

            //WeChatParking.Entity.Api.FeeQuery feeQuery = bll.GetFeeQuery(String.Format(" State=1 "), "create_time");
            if (feeQuery != null)
            {
                code = feeQuery.DeviceClient_code;
                WeChatParking.Entity.Api.ApiFeeQuery model = new WeChatParking.Entity.Api.ApiFeeQuery();
                model.Signlen = 0;
                model.Sign = "";
                model.Func_no = (short)WeChatParking.Entity.Enums.Func_no.FeeQuery;

                model.Car_plate = feeQuery.Car_plate;
                model.Time = feeQuery.Time;
                model.Guid = feeQuery.Guid;
                string Sign = PublicManage.GetSign(model);
                var SignArr = ByteUtil.getBytes(Sign);
                model.Signlen = SignArr.Length;
                model.Sign = Sign;
                //签名长度
                var SignLenArr = ByteUtil.getBytes(PublicManage.formatInt(model.Signlen, 10));
                //功能号
                var Func_noArr = ByteUtil.getBytes(PublicManage.formatInt((short)model.Func_no, 1));
                //车牌
                var Car_plateArr = ByteUtil.getBytes(PublicManage.formatTxt(model.Car_plate, 16));
                //进场时间
                var TimeArr = ByteUtil.getBytes(model.Time);
                //Guid
                var GuidArr = ByteUtil.getBytes(PublicManage.formatTxt(model.Guid, 32));
                var byteArray = (((//签名长度
                  (SignLenArr.Concat(SignArr).ToArray())//签名
                  .Concat(Func_noArr).ToArray())//功能号
                  .Concat(Car_plateArr).ToArray())//车牌号
                  .Concat(TimeArr).ToArray())//时间
                  .Concat(GuidArr).ToArray();//Guid
                //bll.UpdateFeeQuery(feeQuery.Guid, 2);
                return byteArray;
            }
            else
                return null;
        }

        #endregion
    }
}
